package org.acghub.reflection.module;

import org.reflections.Reflections;
import org.reflections.util.ConfigurationBuilder;

import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;

final class ModuleWrapper implements ReflectionModule, Comparable<ModuleWrapper> {
    private final AbstractReflectionModule delegate;
    private final ReflectionModuleAnno anno;

    ModuleWrapper(AbstractReflectionModule delegate, ReflectionModuleAnno anno) {
        this.delegate = delegate;
        this.anno = anno;
    }

    void setReflections(Collection<String> packages) {
        Reflections reflections = new Reflections(new ConfigurationBuilder().forPackages(packages.toArray(new String[0])));
        delegate.setReflections(reflections);
    }

    Reflections replaceReflections(Reflections reflections) {
        return delegate.replaceReflections(reflections);
    }

    @Override
    public Reflections reflections() {
        return delegate.reflections();
    }

    @Override
    public void init() {
        delegate.init();
    }


    @Override
    public void reload() {
        delegate.reload();
    }

    @Override
    public void exit() {
        delegate.exit();
    }


    String getName() {
        String name = anno.name();
        if (name == null || name.isEmpty()) {
            name = delegate.getClass().getSimpleName();
            name = name.substring(0, 1).toLowerCase() + name.substring(1);
        }
        return name;
    }

    List<String> getPackages() {
        String[] packages = anno.packages();
        return (packages == null || packages.length == 0) ? List.of(delegate.getClass().getPackage().getName()) : List.of(packages);
    }

    Set<Class<? extends ReflectionModule>> getDependencies() {
        if (anno.dependencies().length == 0) {
            return Collections.emptySet();
        }
        return Set.of(anno.dependencies());
    }

    int getPriority() {
        return anno.priority();
    }

    AbstractReflectionModule delegate() {
        return delegate;
    }

    ReflectionModuleAnno anno() {
        return anno;
    }

    @Override
    public int compareTo(ModuleWrapper o) {
        return Integer.compare(getPriority(), o.getPriority());
    }
}
